﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using CAION2.Classes;
using CAION2.Properties;
using FirstFloor.ModernUI.Presentation;
using System;
using System.Windows.Media;

namespace CAION2.ViewModels
{
    /// <summary>
    /// A simple view model for configuring theme, font and accent colors.
    /// </summary>
    public class SettingsViewModel
        : NotifyPropertyChanged
    {
        private readonly string _fontSmall = Resources.FontSmall;
        private readonly string _fontLarge = Resources.FontLarge;

        private const string LanguageRu = "Русский";
        private const string LanguageEn = "English";

        //const string ExistingFileName = @"CAION2.exe";

        // use colors from metro design principles
        private static readonly Color[] AccentColorsList = {
                                
                                                               Color.FromRgb(0xa4, 0xc4, 0x00),   // lime
                                                               Color.FromRgb(0x60, 0xa9, 0x17),   // green
                                                               Color.FromRgb(0x00, 0x8a, 0x00),   // emerald
                                                               Color.FromRgb(0x00, 0xab, 0xa9),   // teal
                                                               Color.FromRgb(0x1b, 0xa1, 0xe2),   // cyan
                                                               Color.FromRgb(0x00, 0x50, 0xef),   // cobalt
                                                               Color.FromRgb(0x6a, 0x00, 0xff),   // indigo
                                                               Color.FromRgb(0xaa, 0x00, 0xff),   // violet
                                                               Color.FromRgb(0xf4, 0x72, 0xd0),   // pink
                                                               Color.FromRgb(0xd8, 0x00, 0x73),   // magenta
                                                               Color.FromRgb(0xa2, 0x00, 0x25),   // crimson
                                                               Color.FromRgb(0xe5, 0x14, 0x00),   // red
                                                               Color.FromRgb(0xfa, 0x68, 0x00),   // orange
                                                               Color.FromRgb(0xf0, 0xa3, 0x0a),   // amber
                                                               Color.FromRgb(0xe3, 0xc8, 0x00),   // yellow
                                                               Color.FromRgb(0x82, 0x5a, 0x2c),   // brown
                                                               Color.FromRgb(0x6d, 0x87, 0x64),   // olive
                                                               Color.FromRgb(0x64, 0x76, 0x87),   // steel
                                                               Color.FromRgb(0x76, 0x60, 0x8a),   // mauve
                                                               Color.FromRgb(0x87, 0x79, 0x4e),   // taupe
                                                               Colors.Black,
                                                               Colors.White
                                                           };

        private Color _selectedAccentColor;
        private readonly LinkCollection _themes = new LinkCollection();
        private Link _selectedTheme;
        
        private string _selectedFontSize;
        private string _selectedInterfaceLanguage;
        private string _selectedItemsLanguage;

        private byte _maxDeepLevel;
        private byte _maxDeepLevelForMulti;


        public SettingsViewModel()
        {
            // add the default themes
            _themes.Add(new Link { DisplayName = Resources.Theme_Dark, Source = new Uri("/CAION2;component/Assets/ModernUI.Dark.xaml", UriKind.Relative) });
            _themes.Add(new Link { DisplayName = Resources.Theme_Light, Source = new Uri("/CAION2;component/Assets/ModernUI.Light.xaml", UriKind.Relative) });

            // add additional themes
            _themes.Add(new Link { DisplayName = "AION", Source = new Uri("/CAION2;component/Assets/ModernUI.Aion.xaml", UriKind.Relative) });
            _themes.Add(new Link { DisplayName = Resources.Theme_Bing, Source = new Uri("/CAION2;component/Assets/ModernUI.BingImage.xaml", UriKind.Relative) });
            _themes.Add(new Link { DisplayName = Resources.Theme_HelloKitty, Source = new Uri("/CAION2;component/Assets/ModernUI.HelloKitty.xaml", UriKind.Relative) });
            _themes.Add(new Link { DisplayName = Resources.Theme_Love, Source = new Uri("/CAION2;component/Assets/ModernUI.Love.xaml", UriKind.Relative) });
            _themes.Add(new Link { DisplayName = Resources.Theme_Showflakes, Source = new Uri("/CAION2;component/Assets/ModernUI.Snowflakes.xaml", UriKind.Relative) });

            SelectedFontSize = AppearanceManager.Current.FontSize == FontSize.Large ? _fontLarge : _fontSmall;

            SyncThemeAndColor();
            AppearanceManager.Current.PropertyChanged += OnAppearanceManagerPropertyChanged;
            
            SelectedInterfaceLanguage = ClassConfiguration.GetValue("InterfaceLanguage").ToString() == "ru-RU" ? LanguageRu : LanguageEn;
            SelectedItemsLanguage = ClassConfiguration.GetValue("ItemsLanguage").ToString() == "ru" ? LanguageRu : LanguageEn;

            MaxDeepLevel = Convert.ToByte(ClassConfiguration.GetValue("MaxDeepLevel"));
            MaxDeepLevelForMulti = Convert.ToByte(ClassConfiguration.GetValue("MaxDeepLevelForMulti"));
        }

        private void SyncThemeAndColor()
        {
            // synchronizes the selected viewmodel theme with the actual theme used by the appearance manager.
            SelectedTheme = _themes.FirstOrDefault(l => l.Source.Equals(AppearanceManager.Current.ThemeSource));

            // and make sure accent color is up-to-date
            SelectedAccentColor = AppearanceManager.Current.AccentColor;
        }

        private void OnAppearanceManagerPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ThemeSource" || e.PropertyName == "AccentColor")
            {
                SyncThemeAndColor();
            }
        }

        public LinkCollection Themes
        {
            get { return _themes; }
        }

        public IEnumerable<string> FontSizes
        {
            get { return new[] { _fontSmall, _fontLarge }; }
        }

        public static Color[] AccentColors
        {
            get { return AccentColorsList; }
        }

        public IEnumerable<string> InterfaceLanguages
        {
            get { return new[] { LanguageRu, LanguageEn }; }
        }

        public IEnumerable<string> ItemsLanguages
        {
            get { return new[] { LanguageRu, LanguageEn }; }
        }
        
        public Link SelectedTheme
        {
            get { return _selectedTheme; }
            set
            {
                if (_selectedTheme == value) return;
                _selectedTheme = value;
                OnPropertyChanged("SelectedTheme");

                // and update the actual theme
                AppearanceManager.Current.ThemeSource = value.Source;

                SaveSettings("ThemeColor");
            }
        }

        public string SelectedFontSize
        {
            get { return _selectedFontSize; }
            set
            {
                if (_selectedFontSize == value) return;
                _selectedFontSize = value;
                OnPropertyChanged("SelectedFontSize");

                AppearanceManager.Current.FontSize = value == _fontLarge ? FontSize.Large : FontSize.Small;
                SaveSettings("FontSize");
            }
        }

        public Color SelectedAccentColor
        {
            get { return _selectedAccentColor; }
            set
            {
                if (_selectedAccentColor == value) return;
                _selectedAccentColor = value;
                OnPropertyChanged("SelectedAccentColor");

                if (AppearanceManager.Current.AccentColor == value) return;
                AppearanceManager.Current.AccentColor = value;
                SaveSettings("AccentColor");
            }
        }

        public string SelectedInterfaceLanguage
        {
            get { return _selectedInterfaceLanguage; }
            set
            {
                if (_selectedInterfaceLanguage == value) return;
                
                _selectedInterfaceLanguage = value;
                OnPropertyChanged("SelectedInterfaceLanguage");

                SaveSettings("InterfaceLanguage");
            }
        }

        public string SelectedItemsLanguage
        {
            get { return _selectedItemsLanguage; }
            set
            {
                if (_selectedItemsLanguage == value) return;
                _selectedItemsLanguage = value;
                OnPropertyChanged("SelectedItemsLanguage");

                SaveSettings("ItemsLanguage");
            }
        }

        public byte MaxDeepLevel
        {
            get { return _maxDeepLevel; }
            set
            {
                if (_maxDeepLevel == value) return;

                _maxDeepLevel = value;
                OnPropertyChanged("MaxDeepLevel");

                SaveSettings("MaxDeepLevel");
            }
        }

        public byte MaxDeepLevelForMulti
        {
            get { return _maxDeepLevelForMulti; }
            set
            {
                if (_maxDeepLevelForMulti == value) return;

                _maxDeepLevelForMulti = value;
                OnPropertyChanged("MaxDeepLevelForMulti");

                SaveSettings("MaxDeepLevelForMulti");
            }
        }

        private void SaveSettings(string set)
        {
            switch (set)
            {
                case "ThemeColor":
                    ClassConfiguration.SetValue("ThemeColor", AppearanceManager.Current.ThemeSource.ToString());
                    break;
                case "FontSize":
                    ClassConfiguration.SetValue("FontSize", AppearanceManager.Current.FontSize.ToString());
                    break;
                case "AccentColor":
                    ClassConfiguration.SetValue("AccentColor", Array.FindIndex(AccentColors, p => p == AppearanceManager.Current.AccentColor));
                    break;
                case "InterfaceLanguage":
                    ClassConfiguration.SetValue("InterfaceLanguage", SelectedInterfaceLanguage == LanguageRu ? "ru-RU" : "en-US");
                    break;
                case "ItemsLanguage":
                    ClassConfiguration.SetValue("ItemsLanguage", SelectedItemsLanguage == LanguageRu ? "ru" : "en");
                    break;
                case "MaxDeepLevel":
                    ClassConfiguration.SetValue("MaxDeepLevel", MaxDeepLevel);
                    break;
                case "MaxDeepLevelForMulti":
                    ClassConfiguration.SetValue("MaxDeepLevelForMulti", MaxDeepLevelForMulti);
                    break;
            }
            
        }

    }
}
